﻿// Learn more about F# at http://fsharp.net

// Copyright (c) Microsoft Corporation 2005-2006.
// This sample code is provided "as is" without warranty of any kind. 
// We disclaim all warranties, either express or implied, including the 
// warranties of merchantability and fitness for a particular purpose. 

// FSharp sample - text editor 


open System
open System.IO  
open System.Windows.Forms
open System.ComponentModel;
open System.Diagnostics;

let form = new Form(Width= 800, Height = 600, Visible = true, Text = "PI ADL Compiler", Menu = new MainMenu())

// menu bar and menus 
let mFile = form.Menu.MenuItems.Add("&File")
let mEdit = form.Menu.MenuItems.Add("Edit")
let mView = form.Menu.MenuItems.Add("View")
let mBuild = form.Menu.MenuItems.Add("Build")
let mHelp = form.Menu.MenuItems.Add("&Help")

// menu items 
let miOpen  = new MenuItem("&Open...")
let miSave = new MenuItem("&Save")
let miSaveAs  = new MenuItem("&Save As...")
let miQuit  = new MenuItem("&Quit")
let miAbout = new MenuItem("&About...")
let miCopy = new MenuItem("&Copy...")
let miPaste = new MenuItem("&Paste...")
let miCut = new MenuItem("Cu&t...")
let miCompile = new MenuItem("Compi&le...")
let miClean = new MenuItem("Clea&n")
let miComponentView = new MenuItem("Component &View...")
let miRunTimeView = new MenuItem ("&Run Time View")


mFile.MenuItems.Add(miOpen)
mFile.MenuItems.Add(miSave)
mFile.MenuItems.Add(miSaveAs)
mFile.MenuItems.Add(miQuit)
mHelp.MenuItems.Add(miAbout)
mView.MenuItems.Add(miComponentView)
mView.MenuItems.Add(miRunTimeView)
mEdit.MenuItems.Add(miCopy)
mEdit.MenuItems.Add(miPaste)
mEdit.MenuItems.Add(miCut)
mBuild.MenuItems.Add(miCompile)
mBuild.MenuItems.Add(miClean)

// RichTextBox - text area 
let textB = new RichTextBox(Dock=DockStyle.Fill)
form.Controls.Add(textB)

// filename state 
let mutable filename = ""
let SetFilename f  = filename <- f; form.Text <- "Editor - " + f

// initial state   
SetFilename "echo.pi"
textB.Text <- ""

let mutable current_file_name = ""

// ReadFile dialog 
let ReadFile () =
    let d = new OpenFileDialog() 
    d.Filter <- "adl script files *.pi|*.pi|All files *.*|*.*";
    d.FilterIndex <- 2;
    if d.ShowDialog() = DialogResult.OK then
        let str  = new StreamReader(d.FileName)
        current_file_name <- d.FileName
        let text = str.ReadToEnd ()
        str.Close()
        Some (d.FileName,text)
    else
        None

//SaveFile
let SaveFile text =
    let sw = new StreamWriter(current_file_name)
    sw.Write(text:string); // type constrain text to resolve sw.Write(_) method overload 
    sw.Close();


// SaveFile dialog 
let SaveFileAs file text =
    let d = new SaveFileDialog() 
    d.Filter <- "adl script files *.pi|*.pi|All files *.*|*.*";
    d.FilterIndex <- 2;
    d.FileName <- file;
    d.AddExtension <- false;  
    d.OverwritePrompt <- true;
    if d.ShowDialog() = DialogResult.OK then
        let sw = new StreamWriter(d.FileName)
        sw.Write(text:string); // type constrain text to resolve sw.Write(_) method overload 
        sw.Close();
        Some d.FileName
    else
        None

// ops 
let opLoadText _ = 
    match ReadFile () with
    | Some (file,text) -> SetFilename file; textB.Text <- text
    | None -> ()

let opSaveText _ =
    SaveFile textB.Text
    ()

let opSaveTextAs _ = 
    match SaveFileAs filename textB.Text with
    | Some file -> SetFilename file
    | None -> ()

let opAbout _ = 
    MessageBox.Show("A compiler for PI ADL.","About PI ADL Compiler") |> ignore

let opExitForm _ = form.Close ()

let opCompile _ = 
    opSaveText()
    Process.Start("YaccLexing.exe", current_file_name)
    ()

let opComponentView _ =
    Process.Start("uDrawGraph.exe", "-server")
    Process.Start("ToGraph.exe")
    ()

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////Print AST///////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// callbacks 
let _ = miOpen.Click.Add(opLoadText)
let _ = miSaveAs.Click.Add(opSaveTextAs)
let _ = miSave.Click.Add(opSaveText)

let _ = miQuit.Click.Add(opExitForm)
let _ = miAbout.Click.Add(opAbout)
let _ = miCompile.Click.Add(opCompile)
let _ = miComponentView.Click.Add(opComponentView)

#if COMPILED
// Run the main code. The attribute marks the startup application thread as "Single 
// Thread Apartment" mode, which is recommended for .NET GUI applications. 
[<STAThread()>]    
do Application.Run(form)
#endif

